import os,math ;
from PyQt4.QtCore import QObject,pyqtSignal
from KDataBase.KQueryDB import KQueryDB
from KModel.KSingleStockDataProcessor import KSingleStockDataProcessor as kprocesser
from KModel.KSingleStockCursor import KSingleStockCursor 
import pandas as pd
import numpy as np
import datetime
class KSingleStock(QObject):
	''' class represents a single stock, responsible for:
	1) to interact with database and maintain basic stock information: KSingleStock
	2) resampling and cropping data: KSingleStockDataProcessor
	3) provide window and coordiant mapping information to charts: KSingleStockCurosr
	'''
	dimdict={'open':0,'high':1,'low':2,'close':3,'volumn':4}
	def __init__(self,parent=None):
		QObject.__init__(self)
		self.kcursor=KSingleStockCursor(self)# create cursor to maintain window and current position related
		
		## Wrap a few methods from KSingleStockCursor
		for m in [ 'GetTotalLength', 'GetWindowLength','SetWindowLength','GetAllowedWindowLength', 'SetCursorPostion', 'GetDatesByIndex', 'CurWindowRange',
	        'CurWindowData','GetCurData','GetCurPeriod']: 
			setattr(self, m, getattr(self.kcursor, m))
	
	@staticmethod
	def GetDimensionIndexByName(dimname):
		return KSingleStock.dimdict[dimname]

		
	def __ToDataFrame(self):
		# convert the data inside object into pandas DataFrame Format
		datasource=self.GetCurData()
		timelabels=[str(x) for x in datasource[0]]
		timelabels=[datetime.datetime(int(x[0:4]),int(x[4:6]),int(x[6:8])) for x in timelabels]
		pricedata=datasource[1]
		columnames=['open','high','low','close','volumn']
		self.stkframe=pd.DataFrame(pricedata,index=timelabels,columns=columnames)
		
	
	def GetDataFrame(self):
		# get the stock data stored in terms of pandas DataFrame
		return self.stkframe
		
	
	def GetNumpyArray(self):
		return self.nparray	
	
	def __ToNumpyArray(self):
		datasource=self.GetCurData()
		pricedata=np.array(datasource[1])
		self.nparray=pricedata
		
	def GetOrigData(self):
		return self.origdata
	
	def SetTick(self,country,market,symbol,timerange=None,period=1):
	# iniatialize instance with required country,market and symbol label
		QObject.__init__(self)
		self.country=country
		self.market=market
		self.symbol=symbol

		self.origdata=KQueryDB.QueryStockByDateRange(country,market,symbol)# in term of [date, [open high low close vol]] 
		self.kcursor.SetTick(self.origdata,timerange,period)
		self.__ToDataFrame() # buffer the data in a dataframe format
		self.__ToNumpyArray()

	def ChangePeriod(self,period):
		allowedrange=self.GetAllowedPeriodLength()
		period=int(period)
		if period>allowedrange[1] or period<allowedrange[0]: #should not overpass the limit
			return False
		else:
			flag=self.kcursor.ChangePeriod(self.origdata,period)
			self.__ToDataFrame() # buffer the data in a dataframe format
			self.__ToNumpyArray()
			return flag


	def GetSymbolName(self):
		return "%s.%s.%s" %(self.symbol,self.market,self.country)


	def GetAllowedPeriodLength(self):# periods means how many days per bar
		lowerbound=1
		upperbound=int(math.ceil(len(self.origdata[0])/self.kcursor.GetWindowLength())) 
		#upperbound=int(math.ceil(len(self.origdata[0])/10)) # should allow at least ten bar.
		return [lowerbound,upperbound+1]# +1 because the slicing of python can not reach uppperbound if set as [lowerbound,upperbound]



	def GetPriceByDate(self,sdate):
		# get the price of specific date, not recommend to use since index of list is not efficient.

		if len(self.origdata)>0:
			try:
				sindex=self.origdata[0].index(sdate)
				return self.origdata[1][sindex]
			except:
				return []


